package com.pjl.restartlife.utile;

import jakarta.servlet.http.HttpServletResponse;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.Random;

/**
 * 功能描述
 * 验证码工具类
 * @author: jiaoli
 * @date: 2024年04月07日 14:30
 */
public class AuthCodeUtil {
    /**
     * 定义图形大小
     */
    private static final int width = 105;
    /**
     * 定义图形大小
     */
    private static final int height = 35;

    /**
     * 定义干扰线数量
     */
    private static final int count = 200;

    /**
     * 干扰线的长度=1.414*lineWidth
     */
    private static final int lineWidth = 2;

    /**
     * 图片格式
     */
    private static final String IMG_FORMAT = "JPEG";

    /**
     * base64 图片前缀
     */
    private static final String BASE64_PRE = "data:image/jpg;base64,";

    /**
     * 通过response 返回图片
     * @param response
     * @param resultCode
     * @throws IOException
     */
    public static void generate(HttpServletResponse response,String resultCode) throws IOException {
        BufferedImage image = getImageBuffer(resultCode);
        // 输出图象到页面
        ImageIO.write(image,IMG_FORMAT,response.getOutputStream());
    }

    /**
     * 生成base64字符串
     * @param resultCode
     * @return
     * @throws IOException
     */
    public static String generate(String resultCode) throws IOException {
        BufferedImage image =getImageBuffer(resultCode);
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        // 写入流
        ImageIO.write(image,IMG_FORMAT,byteArrayOutputStream);
        // 转换成字节
        byte[] bytes = byteArrayOutputStream.toByteArray();
        // 转换成base64串
        String base64 = Base64.getEncoder().encodeToString(bytes);
        // 删除 \n
        base64 = base64.replaceAll("\n","");
        return BASE64_PRE+base64;
    }

    /**
     * 生成image
     * @param resultCode
     * @return
     */
    private static BufferedImage getImageBuffer(String resultCode) {
        // 在内在中创建图
        final BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        // 获取图上下文
        final Graphics2D graphics = (Graphics2D) image.getGraphics();
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, width, height);
        graphics.drawRect(0, 0, width-1, height-1);
        final Random random = new Random();
        // 随机生成干扰线
        for(int i = 0; i < count; i++){
            // 设定边框颜色
            graphics.setColor(getRandColor(150, 200));
            // 干扰线画在边框内
            final int x = random.nextInt(width - lineWidth -1) + 1;
            final int y = random.nextInt(height - lineWidth -1) + 1;
            final int xl = random.nextInt(lineWidth);
            final int yl = random.nextInt(lineWidth);
            graphics.drawLine(x, y, x + xl, y + yl);
        }
        // 随机生成验证码
        for(int i = 0 ; i < resultCode.length(); i++){
            graphics.setColor(Color.black);
            graphics.setFont(new Font("Times New Roman", Font.BOLD, 24));
            graphics.drawString(String.valueOf(resultCode.charAt(i)), (23 * i) + 8, 26);
        }
        // 图象生效
        graphics.dispose();
        return image;
    }

    /**
     * 生成颜色
     * @param fc
     * @param bc
     * @return
     */
    private static Color getRandColor(int fc, int bc) {
        final Random random = new Random();
        if (fc > 255){
            fc = 255;
        }
        if (bc > 255){
            bc = 255;
        }
        final int r = fc + random.nextInt(bc - fc);
        final int g = fc + random.nextInt(bc - fc);
        final int b = fc + random.nextInt(bc - fc);
        return new Color(r,g,b);
    }
}
